<!--
 * @Author: 噜噜雯雯 2199987619@qq.com
 * @Date: 2025-06-20 13:52:56
 * @LastEditors: 噜噜雯雯 2199987619@qq.com
 * @LastEditTime: 2025-09-28 15:40:38
 * @FilePath: \linePatrol\vue-element-plus-admin\src\views\GIS\OneMap\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->

<script setup lang="ts">
import AMapLoader from '@amap/amap-jsapi-loader'
import { computed, onMounted, provide, ref, watch } from 'vue'
import { asyncComputed } from '@vueuse/core'
import { Dialog } from '@/components/Dialog'
import LineDetail from './LineDetail.vue'
import Search from './Search.vue'
import HideDangerVue from './HideDanger.vue'
import Level from './Level.vue'
import QueryVue from './Query.vue'
import PointDetail from './PointDetail.vue'
import { useGISStore } from '@/store/modules/gis'
import { useDictStore } from '@/store/modules/dictData'
import { useSCADAStore } from '@/store/modules/scada'
import SCADAApi from '@/api/scada'
import OnLine from '@/assets/imgs/OnLine.png'
import OffLine from '@/assets/imgs/OffLine.png'
import Alarm from '@/assets/imgs/Alarm.png'
const PATH_URL = import.meta.env.VITE_API_PHOTO_PATH

const GISStore = useGISStore()
GISStore.setPipeLineInfo() //管线
GISStore.setPipePointInfo() //管点
const PipeLineInfo = computed(() => {
  return GISStore.getPipeLineInfo
})
const dialogVisible = ref(false)
const QueryVisible = ref(false)
onMounted(() => {
  initMap()
  GISStore.setHideDangerList({ eventState: '', eventGroup: 'event_group_0' }) //获取应急隐患
})
watch(
  () => PipeLineInfo.value,
  () => {
    initMap()
    // updateMonacoVal(props.modelValue)
  }
)
const DictStore = useDictStore()
//获取字典
DictStore.setDict('pipe_line_type') //管线类型字典：决定管线颜色
const actionType = ref('') //点线区分类型
const MarkerData = ref() //标注点详情
let map: any
const markers = [] as any //标注点
const DangerMarkers = [] as any //隐患标注点
const Markers = [] as any //隐患标注点
let infoWindows: {
  setContent: (arg0: any) => void
  open: (arg0: any, arg1: number[]) => void
} //信息窗控件
const polylines = [] as any //管线数组
const ControlMarker = ref(true) //控制缩放显示
const scadaStore = useSCADAStore()
//获取站点数据
const MarkersData = asyncComputed(async () => {
  if (scadaStore.getMarkerList.length === 0) {
    const data = await SCADAApi.GetMarkerList()
    scadaStore.setMarkerList(data)
    return data
  }
  return scadaStore.getMarkerList
})
function initMap() {
  AMapLoader.load({
    key: 'cdaa418d97b829c9ca7590fa62799ac5', // 申请好的Web端开发者Key，首次调用 load 时必填
    version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
    plugins: ['AMap.MoveAnimation'] // 需要使用的的插件列表，如比例尺'AMap.Scale'等
  }).then(async (AMap) => {
    map = new AMap.Map('item3Map', {
      resizeEnable: false,
      //设置地图容器id
      viewMode: '2D', //是否为3D地图模式
      zoom: 13, //初始化地图级别
      center: [115.95, 35.59] //初始化地图中心点位置
    })
    //鼠标退出，关闭浮窗
    const hideInfoWindow = () => {
      map.clearInfoWindow() // 关闭详细信息的浮窗，地图方法
    }
    //
    infoWindows = new AMap.InfoWindow({
      isCustom: true,
      offset: new AMap.Pixel(10, -15) // 偏移量
    })
    //鼠标进入，创建浮窗
    const showInfoWindow = (data: string | undefined, e: any) => {
      const info = [] as any
      // 组成一个要显示的dom，class可以增加对应的css，不过要加scoped可能不起作用，加scoped的话，less或者sass 可以用deep
      info.push(`<p class='TipCard'> ${data}</p>`)
      infoWindows.setContent(info.join(''))
      infoWindows.open(map, e) // 打开弹窗
    }

    //地图缩放显示标注点
    map.on('zoomchange', () => {
      const zoom = map.getZoom()
      if (zoom >= 13.5 && ControlMarker.value == true) {
        // 创建点覆盖物
        GISStore.PipePointInfo.map((item: any) => {
          const startIcon = new AMap.Icon({
            // 图标尺寸
            size: new AMap.Size(item?.mapDropStyle?.iocnSize, item?.mapDropStyle?.iocnSize),
            // 图标的取图地址
            image: `${PATH_URL}${item?.mapDropStyle?.mapIocn}`,
            // 图标所用图片大小
            imageSize: new AMap.Size(item?.mapDropStyle?.iocnSize, item?.mapDropStyle?.iocnSize)
            // 图标取图偏移量
          })
          const marker = new AMap.Marker({
            map: map,
            position: [item.lon, item.lat],
            icon: startIcon,
            extData: item,
            offset: new AMap.Pixel(-17, -35)
          })

          marker.on('mouseover', function (e: any) {
            // 显示这个marker点详细信息的浮窗，这个要放单独方法调用才能显示，暂时不明白为什么，直接把方法内的东西写在下面浮窗并不显示
            showInfoWindow(item.facName, e.lnglat)
          })
          console.log(marker)

          marker.on('mouseout', hideInfoWindow)
          marker.on('click', function () {
            actionType.value = 'point'
            MarkerData.value = item
            dialogVisible.value = true //打开弹窗
          })
          markers.push(marker)
        })
      } else {
        map.remove(markers)
      }
    })
    //隐患
    GISStore.getHideDangerList.map((item) => {
      const startIcon = new AMap.Icon({
        // 图标尺寸
        size: new AMap.Size(35, 35),
        // 图标的取图地址
        image: item.imgFile,
        // 图标所用图片大小
        imageSize: new AMap.Size(35, 35)
        // 图标取图偏移量
      })
      const marker = new AMap.Marker({
        map: map,
        position: [item.lon, item.lat],
        icon: startIcon,
        extData: item,
        offset: new AMap.Pixel(-17, -35)
      })
      marker.on('mouseover', function (e: any) {
        // 显示这个marker点详细信息的浮窗，这个要放单独方法调用才能显示，暂时不明白为什么，直接把方法内的东西写在下面浮窗并不显示
        showInfoWindow(item.eventDes, e.lnglat)
      })
      marker.on('mouseout', hideInfoWindow)
      // marker.setMap(map);
      DangerMarkers.push(marker)
    })
    map.remove(DangerMarkers) //隐藏隐患图标控件
    //站点
    MarkersData.value?.map((item) => {
      const imgFile = ref('')
      if (item.marState == 0) {
        imgFile.value = OnLine
      } else if (item.marState == 1) {
        imgFile.value = OffLine
      } else {
        imgFile.value = Alarm
      }
      const startIcon = new AMap.Icon({
        // 图标尺寸
        size: new AMap.Size(20, 30),
        // 图标的取图地址
        image: imgFile.value,
        // 图标所用图片大小
        imageSize: new AMap.Size(20, 30)
        // 图标取图偏移量
      })
      const marker = new AMap.Marker({
        map: map,
        position: [item.lon, item.lat],
        icon: startIcon,
        extData: item,
        offset: new AMap.Pixel(-20, -30),
        context: item.siteName
      })
      // 创建文本标记
      const text = new AMap.Text({
        text: item.siteName,
        position: [item.lon, item.lat],
        style: {
          'background-color': 'rgba(255,255,255,0.7)',
          border: '1px solid #ccc',
          'border-radius': '4px',
          padding: '5px 8px',
          'font-size': '12px',
          color: '#333'
        },
        offset: new AMap.Pixel(5, -30)
      })
      Markers.push(marker)
      Markers.push(text)
    })
    map.remove(Markers) //隐藏隐患图标控件
    //线路
    PipeLineInfo.value.map((item) => {
      const polyline = new AMap.Polyline({
        map: map,
        extData: item,
        path: [
          [item.startLon, item.startLat],
          [item.endLon, item.endLat]
        ],
        showDir: false,
        strokeColor: item.pipeLineType == 'pipe_line_type_2' ? 'red' : 'rgb(29,65,245)', //线颜色
        strokeOpacity: 1, //线透明度
        strokeWeight: 5, //线宽
        strokeStyle: 'solid' //线样式
      })
      polyline.on('click', () => {
        GISStore.setPipeLineDetail(item.uuid)
        actionType.value = 'line'
        dialogVisible.value = true //打开弹窗
      })
      polyline.on('mouseover', function (e: any) {
        // 显示这个marker点详细信息的浮窗，这个要放单独方法调用才能显示，暂时不明白为什么，直接把方法内的东西写在下面浮窗并不显示
        showInfoWindow(item.pipeLineName, e.lnglat)
      })
      polyline.on('mouseout', hideInfoWindow)
      polylines.push(polyline)
      map.add(polyline)
    })
  })
}
//搜索控件
const ChoosePipeLine = (Lon: number, Lat: number, Name: string, type: number, data: any) => {
  map.setZoomAndCenter(14, [Lon, Lat])
  if (type == 0) {
    //设施点
    actionType.value = 'point'
    MarkerData.value = data
    dialogVisible.value = true //打开弹窗
  } else {
    const info = [] as any
    // 组成一个要显示的dom，class可以增加对应的css，不过要加scoped可能不起作用，加scoped的话，less或者sass 可以用deep
    info.push(`<p class='TipCard'> ${Name}</p>`)
    infoWindows.setContent(info.join(''))
    infoWindows.open(map, [Lon, Lat]) // 打开弹窗
  }
}

//图层控件
const ChooseLevel = (type: number, state: string) => {
  const zoom = map.getZoom()
  if (state == 'show') {
    //要隐藏点或线时
    if (type == 0) {
      //隐藏设施
      map.remove(markers)
      ControlMarker.value = false //控制缩放显示
    } else {
      map.remove(polylines)
    }
  } else {
    if (type == 0) {
      if (zoom >= 13.8) {
        ControlMarker.value = true
        markers.map((marker: any) => {
          map.add(marker)
        })
      }
    } else {
      map.remove(polylines)
      polylines.map((polyline: any) => {
        map.add(polyline)
      })
    }
  }
}
//查询控件
const Query = () => {
  QueryVisible.value = true
}
const ShowHideDanger = ref(false)
const ShowMarker = ref(false)
const SetHideDangerCenter = (Lon: number, Lat: number) => {
  map.setZoomAndCenter(14, [Lon, Lat])
}
//隐患控件
const HideDanger = (boolean: boolean) => {
  ShowHideDanger.value = boolean
  if (boolean) {
    DangerMarkers.map((item) => {
      map.add(item)
    })
  } else {
    map.remove(DangerMarkers) //隐藏隐患图标控件
  }
}
//隐患控件
const HideMarker = (boolean: boolean) => {
  ShowMarker.value = boolean
  if (boolean) {
    console.log(boolean)
    Markers.map((item) => {
      map.add(item)
    })
  } else {
    map.remove(Markers) //隐藏隐患图标控件
  }
}
provide('SetHideDangerCenter', SetHideDangerCenter) //将数据和方法导出
</script>

<template>
  <div class="item3-map">
    <div id="item3Map" ref="item3Map"></div>
    <ul class="input-card">
      <Search @changeMap="ChoosePipeLine" />
      <Level @changeMap="ChooseLevel" />
      <li class="input-item" @click="Query">
        <span>查询</span>
      </li>
      <li class="select input-item" v-if="ShowHideDanger" @click="HideDanger(false)">
        <span>隐患</span>
      </li>
      <li class="input-item" v-else @click="HideDanger(true)">
        <span>隐患</span>
      </li>
      <li class="select input-item" v-if="ShowMarker" @click="HideMarker(false)">
        <span>站点</span>
      </li>
      <li class="input-item" v-else @click="HideMarker(true)">
        <span>站点</span>
      </li>
    </ul>
    <HideDangerVue v-if="ShowHideDanger" />
  </div>
  <Dialog v-model="dialogVisible" title="详情">
    <LineDetail v-if="actionType !== 'point'" :current-row="GISStore.getPipeLineDetail" />
    <PointDetail v-else :current-row="MarkerData" />
  </Dialog>
  <Dialog style="width: 1200px" maxHeight="550px" v-model="QueryVisible" title="查询">
    <QueryVue />
  </Dialog>
</template>
<style scoped lang="less">
// .el-scrollbar{
//   height:500px !important;
// }
.input-card {
  width: 150px;
  top: 0px;
  left: 10px;
  bottom: auto;
  position: absolute;
  .select {
    background: #409eff !important;
    color: #fff !important;
  }
  .input-item {
    width: 50px;
    height: 50px;
    margin: 15px 0;
    background: #fff;
    border-radius: 5px;
    color: #666;
    box-sizing: border-box;
    padding: 5px 10px;
    font-size: 13px;
    list-style: none;
    cursor: pointer;
    text-align: center;
    line-height: 30px;
    display: flex;
    // flex-wrap: wrap;
    align-items: center;
    font-style: normal;
    span {
      display: inline-block;
      // width: 15px;
      // height: 15px;
    }
  }
  .input-item:hover {
    background: #409eff;
    color: #fff;
  }
}

:deep(.TipCard) {
  padding: 5px 10px;
  background: rgb(20, 161, 242);
  border: 1px solid #fff;
  border-radius: 4px;
  font-size: 14px;
  color: #fff;
  font-family: '黑体';
}
:deep(.amap-info-content) {
  padding: 0px;
  // padding: 5px 10px !important;
  // border-radius: 4px;
  // font-size: 14px !important;
}
:deep(.amap-copyright),
:deep(.amap-logo) {
  display: none !important;
}
:deep(.amap-info-close) {
  display: none;
}
.input-card .btn:last-child {
  margin-right: 0;
}
.item3-map {
  width: 100%;
  height: 580px;
  position: relative;
  // border: 1px solid blue;

  #item3Map {
    width: 100%;
    height: 100%;
    // border: 1px solid orange;
  }

  :deep(.amap-marker-label) {
    border: none;
    // padding: 10px 20px;
  }
}
</style>
